{ "cells": [ { "cell_type": "markdown", "id": "1885a594", "metadata": {}, "source": [ "[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/pyinat/pyinaturalist/main?filepath=examples%2FData%2520Visualizations%2520-%2520Regional%2520Observation%2520Stats.ipynb)" ] }, { "cell_type": "markdown", "id": "separate-stylus", "metadata": {}, "source": [ "# Regional observation stats\n", "\n", "This example shows how to get some general statistics on all observations in a given region.\n", "See https://www.inaturalist.org/places to find place IDs." ] }, { "cell_type": "code", "execution_count": 1, "id": "thirty-banking", "metadata": { "tags": [] }, "outputs": [], "source": [ "import altair as alt\n", "import pandas as pd\n", "\n", "from pyinaturalist import (\n", " iNatClient,\n", ")\n", "from pyinaturalist.constants import ICONIC_TAXA\n", "\n", "# Create a client for API requests\n", "client = iNatClient()\n", "\n", "# Adjustable values\n", "PLACE_ID = 6\n", "PLACE_NAME = 'Alaska'" ] }, { "cell_type": "markdown", "id": "touched-fusion", "metadata": {}, "source": [ "### General stats\n", "Total observations, unique taxa, identifiers, and observers" ] }, { "cell_type": "code", "execution_count": 2, "id": "indirect-authority", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total observations: 696947\n", "Total taxa observed: 500\n", "Total identifiers: 500\n", "Total observers: 500\n" ] } ], "source": [ "total_observations = client.observations.search(\n", " place_id=PLACE_ID,\n", " verifiable=True,\n", ").count()\n", "print(f'Total observations: {total_observations}')\n", "\n", "species_counts = client.observations.species_counts(\n", " place_id=PLACE_ID,\n", " verifiable=True,\n", ")\n", "print(f'Total taxa observed: {len(species_counts)}')\n", "\n", "identifiers = client.observations.identifiers(place_id=PLACE_ID)\n", "print(f'Total identifiers: {len(identifiers)}')\n", "\n", "observers = client.observations.observers(place_id=PLACE_ID)\n", "print(f'Total observers: {len(observers)}')" ] }, { "cell_type": "markdown", "id": "outside-airline", "metadata": {}, "source": [ "### Stats by iconic taxon\n", "Show a breakdown of observations and taxa observed for each of the iconic taxa (major species groups), using their corresponding icons on iNaturalist.\n", "Here are a couple helper functions to make this easier:" ] }, { "cell_type": "code", "execution_count": null, "id": "preceding-divide", "metadata": {}, "outputs": [], "source": [ "TAXON_IMAGE_URL = 'https://raw.githubusercontent.com/inaturalist/inaturalist/main/app/assets/images/iconic_taxa/{taxon}-75px.png'\n", "iconic_taxa = list(ICONIC_TAXA.values())\n", "iconic_taxa.remove('Unknown')\n", "\n", "\n", "def get_iconic_icon(taxon_name):\n", " return TAXON_IMAGE_URL.format(taxon=taxon_name.lower())\n", "\n", "\n", "# Run one search for each iconic taxon\n", "iconic_taxa_counts = {}\n", "for taxon_name in iconic_taxa:\n", " total_taxon_observations = client.observations.search(\n", " place_id=PLACE_ID,\n", " iconic_taxa=taxon_name,\n", " verifiable=True,\n", " ).count()\n", "\n", " iconic_taxa_counts[taxon_name] = total_taxon_observations\n", " print(f'Total results for {taxon_name}: {total_taxon_observations}')\n", "\n", "# Create a chart, sorted by number of observations, using the appropriate iNaturalist icons\n", "observations_df = pd.DataFrame(\n", " [\n", " {'iconic taxon': k, 'observations': v, 'img': get_iconic_icon(k)}\n", " for k, v in iconic_taxa_counts.items()\n", " ]\n", ")\n", "alt.Chart(\n", " observations_df,\n", " title=f'Verifiable observations in {PLACE_NAME} by iconic taxon',\n", " width=750,\n", " height=500,\n", ").mark_image().encode(x=alt.X('iconic taxon:N', sort='-y'), y='observations:Q', url='img')" ] }, { "cell_type": "markdown", "id": "medium-joining", "metadata": {}, "source": [ "#### Observations\n", "![total_observations_by_iconic_taxon.png](images/total_observations_by_iconic_taxon.png)" ] }, { "cell_type": "code", "execution_count": null, "id": "interim-republic", "metadata": { "scrolled": true, "tags": [ "nbsphinx-thumbnail" ] }, "outputs": [], "source": [ "# Run one search for each iconic taxon\n", "total_taxa_by_iconic_taxon = {}\n", "for taxon_name in iconic_taxa:\n", " total_taxon_observations = client.observations.search(\n", " place_id=PLACE_ID,\n", " iconic_taxa=taxon_name,\n", " verifiable=True,\n", " ).count()\n", "\n", " total_taxa_by_iconic_taxon[taxon_name] = total_taxon_observations\n", " print(f'Total results for {taxon_name}: {total_taxon_observations}')\n", "\n", "# Create a chart, sorted by number of observations, using the appropriate iNaturalist icons\n", "taxa_df = pd.DataFrame(\n", " [\n", " {'iconic taxon': k, 'unique taxa': v, 'img': get_iconic_icon(k)}\n", " for k, v in total_taxa_by_iconic_taxon.items()\n", " ]\n", ")\n", "alt.Chart(\n", " taxa_df,\n", " title=f'Unique taxa observed in {PLACE_NAME} by iconic taxon',\n", " width=750,\n", " height=500,\n", ").mark_image().encode(x=alt.X('iconic taxon:N', sort='-y'), y='unique taxa:Q', url='img')" ] }, { "cell_type": "markdown", "id": "unlikely-mongolia", "metadata": {}, "source": [ "#### Taxa\n", "![total_taxa_by_iconic_taxon.png](images/total_taxa_by_iconic_taxon.png)" ] } ], "metadata": { "celltoolbar": "Tags", "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.12" } }, "nbformat": 4, "nbformat_minor": 5 }